#include "WhileLoop.h"
#include "../Exceptions.h"
#include "../GeneralVisitor.h"

WhileLoop::WhileLoop(TreeNode* iCondition, TreeNode* iBody)
{
    fCondition = iCondition;
    fBody = iBody;
}

WhileLoop::~WhileLoop()
{
    delete fCondition;
    delete fBody;
}

void WhileLoop::CheckVariables(set<string>& oVariables, string iParentName)
{
    this->fCondition->CheckVariables(oVariables, iParentName);
    this->fBody->CheckVariables(oVariables, iParentName);
}

void WhileLoop::CheckFunctionCalls(set<FunctionDefinition*>& iAllFunctions, string iParentName)
{
    this->fCondition->CheckFunctionCalls(iAllFunctions, iParentName);
    this->fBody->CheckFunctionCalls(iAllFunctions, iParentName);
}

void WhileLoop::CheckClassConstructions(set<ClassDefinition*>& iAllClasses, string iParentName)
{
    this->fCondition->CheckClassConstructions(iAllClasses, iParentName);
    this->fBody->CheckClassConstructions(iAllClasses, iParentName);
}

void WhileLoop::CheckExpressionTypes(map<string, ExpressionType*>& iVarTypes, string iParentName)
{
    this->fCondition->CheckExpressionTypes(iVarTypes, iParentName);

    ExpressionType* lConditionType = this->fCondition->GetType(iVarTypes, iParentName);
    ValueType lType = lConditionType->fType;

    if(!lConditionType->fResolveTypeAtRuntime && lType != Boolean)
    {
        delete lConditionType;
        throw InvalidTypeException(iParentName, "podminka cyklu while", Boolean, lType);
    }

    delete lConditionType;

    this->fBody->CheckExpressionTypes(iVarTypes, iParentName);
}

void WhileLoop::Accept(GeneralVisitor* iVisitor)
{
    iVisitor->Visit(this);
}

ReturnStatement* WhileLoop::GetFirstReturnStatement()
{
    return fBody->GetFirstReturnStatement();
}
